# -*- coding: utf-8 -*-
"""
---------------------------------------
@File    ：ip_update.py
@Author  ：liyunhui
@Date    ：2024/9/13 下午4:12 
@explain : ip更新
---------------------------------------
"""
# todo：各个拨号云节点调用该接口将更换后的公网IP更新至IP池中
import json
import tornado
import traceback
from tornado import gen
from config import config
from datetime import datetime
from methods.custom_log import create_logging
from methods.redis_connect import get_redis_cli
from concurrent.futures import ThreadPoolExecutor
from tornado_swagger.model import register_swagger_model


@register_swagger_model
class IpUpdateModel:
    """
    ---
    type: object
    description: Post model representation
    properties:
            intranet_ip:
                    type: string
            public_ip:
                    type: etag
    """


class IpUpdateHandler(tornado.web.RequestHandler):
    thread_pool = ThreadPoolExecutor(max_workers=config.max_thread_number)

    def __init__(self, *args, **kwargs):
        super(IpUpdateHandler, self).__init__(*args, **kwargs)
        self.logging = create_logging("ip_update")
        self.use_ip_key = config.use_ips
        self.redis_client = get_redis_cli()

    @gen.coroutine
    def post(self):
        """
        更新或添加 IP 数据
        ---
        tags:
        - IP 更新
        summary: 更新或添加内网 IP 和公网 IP 映射数据
        produces:
            - application/json
        parameters:
          - name: intranet_ip
            in: query
            description: 内网 IP
            required: true
            type: string

          - name: public_ip
            in: query
            description: 公网 IP
            required: true
            type: string

        responses:
          200:
            description: 成功更新 IP 数据
            schema:
              type: object
              properties:
                status:
                  type: string
                  example: success
                intranet_ip:
                  type: string
                public_ip:
                  type: string
          400:
            description: 请求参数错误
            schema:
              type: object
              properties:
                status:
                  type: string
                  example: error
                message:
                  type: string
        """
        try:
            # 解析 JSON 请求体
            params = {key: value[0].decode('utf-8') for key, value in self.request.arguments.items()}
            self.logging.info(f'IP更新任务：{params}')
            # 提取参数
            intranet_ip = params.get('intranet_ip', '')
            status = params.get('status', False)    # 新增一个状态

            # 有些时候内网IP传递会错误
            if intranet_ip in config.ip_classify.get("is_china") or intranet_ip in config.ip_classify.get("no_china"):
                public_ip = params.get('public_ip', '')
                update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                # 先检查一下这个IP是国内还是国外的
                if intranet_ip in config.ip_classify.get("is_china"):
                    ip_class = "is_china"
                else:
                    ip_class = "no_china"
                # 检查并更新 Redis
                redis_key = f"{self.use_ip_key}:{ip_class}:{intranet_ip}"
                if self.redis_client.exists(redis_key):
                    # 如果 IP 存在，更新数据
                    self.redis_client.hset(redis_key, mapping={
                        'public_ip': public_ip,
                        'update_time': update_time,
                        'status': status
                    })
                    self.logging.info(f"更新 IP data: {intranet_ip}")
                else:
                    # 如果 IP 不存在，添加新数据
                    self.redis_client.hset(redis_key, mapping={
                        'public_ip': public_ip,
                        'update_time': update_time,
                        'status': status
                    })
                    self.logging.info(f"新增 new IP data: {intranet_ip}")
                # 返回响应
                response = {
                    'status': 'success',
                    'intranet_ip': intranet_ip,
                    'public_ip': public_ip,
                    'update_time': update_time,
                    'proxy_status': status
                }
                self.set_header("Content-Type", "application/json")
                self.write(json.dumps(response))
            else:
                self.logging.info(f"内外网IP可能传递有误！")
                response = {
                    'status': 'failed',
                    'intranet_ip': None,
                    'public_ip': None,
                    'update_time': None
                }
                self.set_header("Content-Type", "application/json")
                self.write(json.dumps(response))

        except Exception as e:
            error_message = traceback.format_exc()  # 获取完整的异常堆栈信息
            self.set_status(400)
            self.write(json.dumps({'status': 'error', 'message': str(error_message)}))
            self.logging.error(f"{error_message}")
